#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <mqueue.h>
#include "string.h"

// 队列名称
static char *mq_name = "/test_mq"; // / 代表 /dev/mqueue目录
static mqd_t mqd; // 消息队列描述符

// first 线程函数  接收消息
void *first_thread_fun(void *arg)
{
    printf("first线程开始执行 tid = %d\n", gettid());
    char recv_msg[100];
    int priority;
    ssize_t size = mq_receive(mqd, recv_msg, 100, &priority);
    if (size > 0)
    {
        printf("接收到的消息为 %s size为%ld\n", recv_msg, size);
    }
    else
    {
        perror("mq_receive error");
    }
}
// second 线程函数 发送消息
void *second_thread_fun(void *arg)
{
    printf("second线程开始执行 tid = %d\n", gettid());
    sleep(1);

    char *send_msg = "hello world";
    // 参数4 优先级
    mq_send(mqd, send_msg, strlen(send_msg) + 1, 1);
}
int main(int argc, char const *argv[])
{
    // 队列属性 attr 表示消息队列属性
    struct mq_attr attr;
    attr.mq_maxmsg = 10;    // 最大消息数
    attr.mq_msgsize = 100; // 每条消息的最大字节数
    // 创建消息队列
    /**
     * mq_name 队列名称
     * O_CREAT 创建
     * O_RDWR 读写
     * 0666 权限    可读可写不可执行 其他用户，当前用户，组用户
     *  NULL 消息队列属性
     */
    mqd = mq_open(mq_name, O_CREAT | O_RDWR, 0666, &attr);
    if (mqd == -1)
    {
        perror("mq_open error 队列消息创建失败");
        return -1;
    }

    pthread_t pt1, pt2;
    // 参数二 null 默认优先级 参数三 线程函数 参数四 线程函数参数
    pthread_create(&pt1, NULL, first_thread_fun, NULL);
    pthread_create(&pt2, NULL, second_thread_fun, NULL);

    // 等待2个线程执行完毕
    pthread_join(pt1, NULL);
    pthread_join(pt2, NULL);

    // 关闭消息队列
    mq_close(mqd);
    // 删除消息队列
    mq_unlink(mq_name);

    return 0;
}
